#include "CManagerSpace.h"

CManagerSpace::CManagerSpace()
{
}

CManagerSpace::CManagerSpace(std::fstream* archivo)
{
	this->file = archivo;
	this->outfile.open(DB_DELETED,std::ios::binary | std::ios::in);
	this->cargarIndiceBorrados();
}

void CManagerSpace::cargarIndiceBorrados(){
	this->outfile.seekg(0,std::ios::beg);
	DBFrecuencias::CantidadTags tag;
	DBFrecuencias::Offset offset;
	int cantidadTags;
	if(this->outfile.is_open()){
		while(!this->outfile.eof()){
			this->outfile.read(reinterpret_cast<char*>(&tag),sizeof(tag));
			this->outfile.read(reinterpret_cast<char*>(&cantidadTags),sizeof(int));
	
			for(int i=0 ; i < cantidadTags ; i++){
				this->outfile.read(reinterpret_cast<char*>(&offset),sizeof(DBFrecuencias::Offset));
				this->agregarEspacio(tag,offset);
			}
		}
	}
	this->outfile.close();
}

DBFrecuencias::Offset CManagerSpace::consultarEspacio(DBFrecuencias::CantidadTags cant)
{
	DBFrecuencias::IndiceBorrados::iterator it = borrados.find(cant);
	if(it != borrados.end()){
			DBFrecuencias::ListaOffsets* offsets = it->second;
			if(!offsets->empty()){
				DBFrecuencias::Offset o=offsets->front();
				offsets->pop_front();
				return o;
			}else{
				delete(offsets);
				borrados.erase(it);
			}
	}
	file->seekg(0, std::ios::end);
	return file->tellg();

}

DBFrecuencias::MaxFileSize CManagerSpace::agregarEspacio(DBFrecuencias::CantidadTags cant,DBFrecuencias::Offset offset)
{
	DBFrecuencias::IndiceBorrados::iterator it = borrados.find(cant);
	DBFrecuencias::ListaOffsets* offsets=NULL;
	if(it != borrados.end()){
		offsets = it->second;
		if(!this->estaContenido(offsets,offset)){
			offsets->push_back(offset);
		}
	}else{
		offsets = new DBFrecuencias::ListaOffsets();
		offsets->push_back(offset);
		borrados.insert(std::pair<DBFrecuencias::CantidadTags,DBFrecuencias::ListaOffsets*>(cant,offsets));
	}
	return this->espacioOcupado();
}

CManagerSpace::~CManagerSpace(){
	DBFrecuencias::IndiceBorrados::iterator it = borrados.begin();
	//chsize(this->outfile,0);
	this->outfile.open(DB_DELETED,std::ios::binary | std::ios::out | std::ios::trunc);
	//this->outfile.seekp(0,std::ios::beg);
	for( ;it != borrados.end();it++ ){
		DBFrecuencias::ListaOffsets* offsets=it->second;
		if(!offsets->empty()){

			//guarda que tamanio tienen los borrados de la lista
			DBFrecuencias::CantidadTags tags = it->first;
			this->outfile.write(reinterpret_cast<char*>(&tags),sizeof(DBFrecuencias::CantidadTags));
			//guarda la cantidad de borrados para ese tamanio
			int size = offsets->size();
			this->outfile.write(reinterpret_cast<char*>(&size),sizeof(int));
			DBFrecuencias::ListaOffsets::iterator i = offsets->begin();

			for( ;i != offsets->end();i++){
				//guarda uno por uno
				DBFrecuencias::Offset aux = *i;
				this->outfile.write(reinterpret_cast<char*>(&aux),sizeof(DBFrecuencias::Offset));
			}
		}
		delete(offsets);
	}
	outfile.close();
}

void CManagerSpace::eliminarTodo(){
	DBFrecuencias::IndiceBorrados::iterator it = borrados.begin();
	for( ;it != borrados.end();it++ ){
		DBFrecuencias::ListaOffsets* offsets=it->second;
		delete(offsets);
	}
	this->borrados.clear();
}

bool CManagerSpace::estaContenido(DBFrecuencias::ListaOffsets* lista,DBFrecuencias::Offset offset){
	DBFrecuencias::ListaOffsets::iterator it = lista->begin();
	for( ;it != lista->end();it++){
		if((*it)==offset){
			return true;
		}
	}
	return false;
}

//DBFrecuencias::MaxFileSize CManagerSpace::espacioOcupado(){
//	DBFrecuencias::MaxFileSize size = 0;
//	DBFrecuencias::IndiceBorrados::iterator it = this->borrados.begin();  
//	for( ; it != this->borrados.end() ; it++){
//		DBFrecuencias::MaxFileSize recordSize = sizeof(bool) + sizeof(DBFrecuencias::CantidadTags) 
//		+ ((it->first)*sizeof(DBFrecuencias::SElemento));
//		recordSize *= ((DBFrecuencias::ListaOffsets*)(it->second))->size();
//		size += recordSize;
//	}
//	return size;
//}

DBFrecuencias::MaxFileSize CManagerSpace::espacioOcupado(){
	DBFrecuencias::MaxFileSize size = 0;
	DBFrecuencias::IndiceBorrados::iterator it = this->borrados.begin();  
	for( ; it != this->borrados.end() ; it++){
		size += (sizeof(DBFrecuencias::Offset))*((DBFrecuencias::ListaOffsets*)(it->second))->size();
	}
	size += (sizeof(DBFrecuencias::CantidadTags))*(this->borrados.size());
	return size;
}
